<template>
  <div class="kitten-tts-app">
    <el-container>
      <el-header>
        <h1>Kitten TTS - 语音服务平台</h1>
        <p>文字转声音和声音转文字的全能语音处理平台</p>
      </el-header>
      
      <el-main>
        <el-card class="tts-form-card">
          <template #header>
            <div class="card-header">
              <el-tabs v-model="activeTab" @tab-click="handleTabClick">
                <el-tab-pane label="文字转语音" name="tts"></el-tab-pane>
                <el-tab-pane label="录音转文字" name="stt"></el-tab-pane>
                <el-tab-pane label="单词拼读" name="spelling"></el-tab-pane>
              </el-tabs>
            </div>
          </template>
          
          <el-form ref="ttsForm" :model="ttsFormData" label-width="100px">
            <el-form-item label="输入文本">
              <el-input
                v-model="ttsFormData.text"
                type="textarea"
                :rows="6"
                placeholder="请输入要转换的文本..."
                :disabled="loading"
                v-if="activeTab === 'tts'"
              ></el-input>
              
              <!-- 录音转文字区域 -->
              <div v-else-if="activeTab === 'stt'" class="stt-container">
                <div class="stt-controls">
                  <el-button
                    type="primary"
                    @click="handleStartRecording"
                    :disabled="recording || loading"
                    icon="el-icon-microphone"
                    class="stt-btn"
                  >
                    {{ recording ? '录音中...' : '开始录音' }}
                  </el-button>
                  
                  <el-button
                    type="danger"
                    @click="handleStopRecording"
                    :disabled="!recording || loading"
                    icon="el-icon-stop"
                    class="stt-btn"
                  >
                    停止录音
                  </el-button>
                  
                  <el-upload
                    class="upload-audio"
                    :disabled="recording || loading"
                    accept=".wav,.mp3,.ogg"
                    :before-upload="handleAudioUpload"
                    :show-file-list="false"
                  >
                    <el-button
                      type="success"
                      icon="el-icon-upload"
                      class="stt-btn"
                    >
                      上传音频
                    </el-button>
                  </el-upload>
                </div>
                
                <!-- 录音状态 -->
                <div v-if="recording" class="recording-status">
                  <el-progress :percentage="recordingProgress" status="warning" />
                  <p>录音时间: {{ recordingTime }}秒</p>
                </div>
                
                <!-- 上传的音频预览 -->
                <div v-if="audioFile" class="audio-preview">
                  <p>已选择文件: {{ audioFile.name }}</p>
                  <el-button
                    type="text"
                    @click="audioFile = null"
                    :disabled="loading"
                    icon="el-icon-delete"
                  >
                    移除文件
                  </el-button>
                  <audio :src="audioPreviewUrl" controls v-if="audioPreviewUrl"></audio>
                </div>
                
                <!-- 语言选择 -->
                <div class="stt-language-selection">
                  <el-select
                    v-model="sttLanguage"
                    placeholder="选择语言"
                    style="width: 150px;"
                    :disabled="recording || loading"
                  >
                    <el-option label="英语" value="en-US"></el-option>
                    <el-option label="中文(简体)" value="zh-CN"></el-option>
                  </el-select>
                </div>
              </div>
              
              <!-- 单词拼读区域 -->
              <div v-else class="spelling-container">
                <el-input
                  v-model="spellingFormData.word"
                  placeholder="请输入要拼读的单词..."
                  :disabled="loading"
                ></el-input>
                
                <div class="advanced-spelling-options" v-if="useAdvancedSpelling">
                  <el-form-item label="拼读模式" :label-width="'100px'">
                    <el-select v-model="advancedSpellingFormData.mode" style="width: 100%;" :disabled="loading">
                      <el-option label="字母逐一拼读" value="letter_by_letter"></el-option>
                      <el-option label="字母名称拼读" value="letter_name"></el-option>
                      <el-option label="音素拼读" value="phonemic"></el-option>
                      <el-option label="组合拼读" value="combination"></el-option>
                      <el-option label="CRFSuite + CMU词典" value="crfsuite"></el-option>
                    </el-select>
                  </el-form-item>
                  
                  <el-form-item label="字母分隔符" :label-width="'100px'">
                    <el-input v-model="advancedSpellingFormData.letter_separator" placeholder="空格" :disabled="loading" style="width: 100%;"></el-input>
                  </el-form-item>
                  
                  <el-form-item :label-width="'100px'">
                    <el-checkbox v-model="advancedSpellingFormData.with_pronunciation" :disabled="loading">包含发音说明</el-checkbox>
                  </el-form-item>
                  
                  <el-form-item :label-width="'100px'">
                    <el-checkbox v-model="advancedSpellingFormData.with_word_pronunciation" :disabled="loading">包含单词发音</el-checkbox>
                  </el-form-item>
                </div>
                
                <div class="spelling-options">
                  <el-checkbox v-model="useAdvancedSpelling" :disabled="loading">使用高级拼读</el-checkbox>
                </div>
                
                <p class="spelling-hint">提示：输入英文单词，系统将生成该单词的拼读语音</p>
              </div>
            </el-form-item>
            
            <el-form-item label="选择语音">
              <el-select
                v-model="ttsFormData.voice"
                placeholder="请选择语音"
                :disabled="loading || voices.length === 0"
              >
                <el-option
                  v-for="voice in voices"
                  :key="voice"
                  :label="voice"
                  :value="voice"
                ></el-option>
              </el-select>
            </el-form-item>
            
            <el-form-item label="选择语言">
              <el-select
                v-model="ttsFormData.language"
                placeholder="请选择语言"
                :disabled="loading || languages.length === 0"
                @change="onLanguageChange"
              >
                <el-option
                  v-for="lang in languages"
                  :key="lang"
                  :label="getLanguageLabel(lang)"
                  :value="lang"
                ></el-option>
              </el-select>
            </el-form-item>
            
            <el-form-item label="语速">
              <el-row :gutter="20" align="middle">
                <el-col :span="16">
                  <el-slider
                    v-model="ttsFormData.speed"
                    :min="0.5"
                    :max="2.0"
                    :step="0.1"
                    :disabled="loading"
                  ></el-slider>
                </el-col>
                <el-col :span="4">
                  <el-input
                    v-model="ttsFormData.speed"
                    size="small"
                    style="width: 80px;"
                    :disabled="loading"
                  ></el-input>
                </el-col>
              </el-row>
            </el-form-item>
          </el-form>
          
          <div class="form-actions">
            <el-button
              type="primary"
              @click="handleConvert"
              :loading="loading"
              :disabled="loading || !ttsFormData.text.trim() || activeTab !== 'tts'"
              icon="el-icon-sound"
            >
              转换为语音
            </el-button>
            
            <el-button
              type="primary"
              @click="handleRecognizeSpeech"
              :loading="loading"
              :disabled="loading || activeTab !== 'stt' || (!audioFile && !recordingData)"
              icon="el-icon-microphone"
            >
              识别语音
            </el-button>
            
            <el-button
              type="primary"
              @click="useAdvancedSpelling ? handleAdvancedSpelling() : handleSpelling()"
              :loading="loading"
              :disabled="loading || activeTab !== 'spelling' || !spellingFormData.word.trim()"
              icon="el-icon-help"
            >
              {{ useAdvancedSpelling ? '生成高级拼读语音' : '生成拼读语音' }}
            </el-button>
            
            <el-button
              @click="handleClear"
              :disabled="loading"
              icon="el-icon-delete"
            >
              清空
            </el-button>
          </div>
        </el-card>
        
        <!-- 结果展示区域 -->
        <el-card class="result-card" v-if="showResult">
          <template #header>
            <div class="card-header">
              <span>转换结果</span>
            </div>
          </template>
          
          <!-- 加载状态 -->
          <div v-if="loading" class="loading-container">
            <el-loading-spinner></el-loading-spinner>
            <p>正在生成语音...</p>
          </div>
          
          <!-- 错误信息 -->
          <div v-else-if="errorMessage" class="error-container">
            <el-alert
              :title="'错误信息'"
              :message="errorMessage"
              type="error"
              show-icon
              closable
              @close="errorMessage = ''"
            ></el-alert>
          </div>
          
          <!-- 成功结果 -->
          <div v-else-if="audioUrl" class="success-container">
            <el-alert
              title="音频生成成功！"
              message="点击下方播放或下载"
              type="success"
              show-icon
            ></el-alert>
            
            <!-- 显示拼读信息（如果有） -->
            <div v-if="spellingInfo || spellingText" class="spelling-info-container">
              <el-divider content-position="left">拼读信息</el-divider>
              <div v-if="spellingText" class="spelling-text">
                <strong>拼读文本：</strong> {{ spellingText }}
              </div>
              <div v-if="spellingInfo" class="spelling-details">
                <strong>详细信息：</strong> {{ spellingInfo }}
              </div>
            </div>
            
            <div class="audio-controls">
              <audio :src="audioUrl" controls></audio>
              <el-button
                type="primary"
                icon="el-icon-download"
                @click="handleDownload"
                class="download-btn"
              >
                下载音频
              </el-button>
            </div>
          </div>
        </el-card>
      </el-main>
      
      <el-footer>
        <p>&copy; 2023 Kitten TTS Web</p>
      </el-footer>
    </el-container>
  </div>
  
  <!-- 添加单词对话框 -->
  <el-dialog
    v-model="showAddWordDialog"
    title="添加新单词"
    width="500px"
    :before-close="() => { showAddWordDialog = false }"
  >
    <el-form ref="wordForm" :model="newWord" label-width="80px">
      <el-form-item label="单词" prop="word" :rules="[{ required: true, message: '请输入单词', trigger: 'blur' }]">
        <el-input v-model="newWord.word" placeholder="请输入单词"></el-input>
      </el-form-item>
      <el-form-item label="翻译">
        <el-input v-model="newWord.translation" placeholder="请输入翻译"></el-input>
      </el-form-item>
      <el-form-item label="音标">
        <el-input v-model="newWord.phonetic" placeholder="请输入音标"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="showAddWordDialog = false">取消</el-button>
      <el-button type="primary" @click="addWord">确定</el-button>
    </template>
  </el-dialog>
</template>

<script>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import axios from 'axios'
import ttsApi from './utils/api'

export default {
  name: 'App',
  setup() {
    // 表单数据
    const ttsFormData = reactive({
      text: '',
      voice: 'expr-voice-5-m',
      speed: 1.0,
      language: 'en-us'
    })
    
    // 拼读表单数据
    const spellingFormData = reactive({
      word: '',
      voice: 'expr-voice-5-m',
      speed: 1.0
    })
    
    // 高级拼读表单数据
    const advancedSpellingFormData = reactive({
      mode: 'letter_by_letter',
      with_pronunciation: false,
      letter_separator: ' ',
      with_word_pronunciation: false,
      voice: 'expr-voice-5-m',
      speed: 1.0
    })
    
    // 是否使用高级拼读
    const useAdvancedSpelling = ref(false)
    
    // 录音转文字相关状态
    const activeTab = ref('tts')
    const sttLanguage = ref('en-US')
    const recording = ref(false)
    const recordingData = ref(null)
    const recordingTime = ref(0)
    const recordingProgress = ref(0)
    const recordingInterval = ref(null)
    const mediaRecorder = ref(null)
    const audioFile = ref(null)
    const audioPreviewUrl = ref('')
    
    // 状态变量
    const voices = ref([])
    const languages = ref(['en-us', 'zh'])
    const audioUrl = ref('')
    const loading = ref(false)
    const errorMessage = ref('')
    const showResult = ref(false)
    const audioBlob = ref(null)
    const spellingInfo = ref('')
    const spellingText = ref('')
    
    // 获取语言显示标签
    const getLanguageLabel = (lang) => {
      const labels = {
        'en-us': 'English',
        'zh': '中文'
      }
      return labels[lang] || lang
    }
    
    // 加载语音列表
    const loadVoices = async (language = ttsFormData.language) => {
      try {
        const response = await axios.get(`/api/voices?language=${language}`)
        voices.value = response.data.voices || []
        // 如果当前选择的语音不在新列表中，选择第一个
        if (voices.value.length > 0 && !voices.value.includes(ttsFormData.voice)) {
          ttsFormData.voice = voices.value[0]
        }
      } catch (error) {
        console.error('加载语音列表失败:', error)
        voices.value = [
          'expr-voice-2-m', 'expr-voice-2-f', 
          'expr-voice-3-m', 'expr-voice-3-f', 
          'expr-voice-4-m', 'expr-voice-4-f', 
          'expr-voice-5-m', 'expr-voice-5-f'
        ]
      }
    }
    
    // 加载语言列表
    const loadLanguages = async () => {
      try {
        const response = await axios.get('/api/languages')
        languages.value = response.data.languages || ['en-us', 'zh']
      } catch (error) {
        console.error('加载语言列表失败:', error)
        languages.value = ['en-us', 'zh']
      }
    }
    
    // 语言切换处理
    const onLanguageChange = (language) => {
      loadVoices(language)
    }
    
    // 处理转换
    const handleConvert = async () => {
      if (!ttsFormData.text.trim()) {
        errorMessage.value = '请输入要转换的文本'
        showResult.value = true
        return
      }
      
      loading.value = true
      errorMessage.value = ''
      audioUrl.value = ''
      showResult.value = true
      
      try {
        const response = await axios.post('/api/tts', ttsFormData, {
          responseType: 'blob'
        })
        
        // 创建音频URL
        audioBlob.value = new Blob([response.data], { type: 'audio/wav' })
        audioUrl.value = URL.createObjectURL(audioBlob.value)
      } catch (error) {
        console.error('转换失败:', error)
        let errorMsg = '转换失败，请稍后重试'
        if (error.response && error.response.data) {
          if (typeof error.response.data === 'string') {
            errorMsg = error.response.data
          } else if (error.response.data.error) {
            errorMsg = error.response.data.error
          }
        }
        errorMessage.value = errorMsg
      } finally {
        loading.value = false
      }
    }
    
    // 处理单词拼读
    const handleSpelling = async () => {
      if (!spellingFormData.word.trim()) {
        errorMessage.value = '请输入要拼读的单词'
        showResult.value = true
        return
      }
      
      loading.value = true
      errorMessage.value = ''
      audioUrl.value = ''
      showResult.value = true
      
      try {
        const response = await ttsApi.generateSpellingAudio(spellingFormData)
        
        // 创建音频URL
        audioBlob.value = new Blob([response], { type: 'audio/wav' })
        audioUrl.value = URL.createObjectURL(audioBlob.value)
      } catch (error) {
        console.error('拼读语音生成失败:', error)
        errorMessage.value = error.message || '拼读语音生成失败，请稍后重试'
      } finally {
        loading.value = false
      }
    }
    
    // 处理高级单词拼读
    const handleAdvancedSpelling = async () => {
      if (!spellingFormData.word.trim()) {
        errorMessage.value = '请输入要拼读的单词'
        showResult.value = true
        return
      }
      
      loading.value = true
      errorMessage.value = ''
      audioUrl.value = ''
      spellingInfo.value = ''
      spellingText.value = ''
      showResult.value = true
      
      try {
        // 构建请求数据
        const requestData = {
          word: spellingFormData.word,
          mode: advancedSpellingFormData.mode,
          with_pronunciation: advancedSpellingFormData.with_pronunciation,
          letter_separator: advancedSpellingFormData.letter_separator,
          with_word_pronunciation: advancedSpellingFormData.with_word_pronunciation,
          voice: advancedSpellingFormData.voice,
          speed: advancedSpellingFormData.speed
        }
        
        const response = await ttsApi.generateAdvancedSpellingAudio(requestData)
        
        // 创建音频URL
        audioBlob.value = new Blob([response.audio], { type: 'audio/wav' })
        audioUrl.value = URL.createObjectURL(audioBlob.value)
        
        // 保存拼读信息
        spellingInfo.value = response.info || ''
        spellingText.value = response.text || ''
      } catch (error) {
        console.error('高级拼读语音生成失败:', error)
        errorMessage.value = error.message || '高级拼读语音生成失败，请稍后重试'
      } finally {
        loading.value = false
      }
    }
    
    // 处理清空
    const handleClear = () => {
      ttsFormData.text = ''
      spellingFormData.word = ''
      audioUrl.value = ''
      errorMessage.value = ''
      audioBlob.value = null
      showResult.value = false
      
      // 清除录音相关数据
      if (audioFile.value) {
        audioFile.value = null
        if (audioPreviewUrl.value) {
          URL.revokeObjectURL(audioPreviewUrl.value)
          audioPreviewUrl.value = ''
        }
      }
      recordingData.value = null
      recordingTime.value = 0
    }
    
    // 处理下载
    const handleDownload = () => {
      if (!audioBlob.value) return
      
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
      const filename = `tts_${timestamp}.wav`
      
      const url = window.URL.createObjectURL(audioBlob.value)
      const link = document.createElement('a')
      link.href = url
      link.download = filename
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
    }
    
    // 处理选项卡切换
    const handleTabClick = (tab) => {
      showResult.value = false
      errorMessage.value = ''
      
      // 如果切换到拼读选项卡，同步语音和语速设置
      if (tab.name === 'spelling') {
        spellingFormData.voice = ttsFormData.voice
        spellingFormData.speed = ttsFormData.speed
        // 同步高级拼读的设置
        advancedSpellingFormData.voice = ttsFormData.voice
        advancedSpellingFormData.speed = ttsFormData.speed
      }
    }
    
    // 开始录音
    const handleStartRecording = async () => {
      try {
        // 检查浏览器支持
        if (!navigator.mediaDevices || !window.MediaRecorder) {
          errorMessage.value = '您的浏览器不支持录音功能'
          showResult.value = true
          return
        }
        
        // 获取用户媒体权限
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
        
        // 创建媒体录制器
        mediaRecorder.value = new MediaRecorder(stream)
        const audioChunks = []
        
        // 监听数据可用事件
        mediaRecorder.value.ondataavailable = (event) => {
          if (event.data.size > 0) {
            audioChunks.push(event.data)
          }
        }
        
        // 监听录制结束事件
        mediaRecorder.value.onstop = () => {
          const audioBlob = new Blob(audioChunks, { type: 'audio/wav' })
          recordingData.value = audioBlob
          
          // 创建预览URL
          if (audioPreviewUrl.value) {
            URL.revokeObjectURL(audioPreviewUrl.value)
          }
          audioPreviewUrl.value = URL.createObjectURL(audioBlob)
          
          // 停止所有音轨
          stream.getTracks().forEach(track => track.stop())
        }
        
        // 开始录制
        mediaRecorder.value.start()
        recording.value = true
        recordingTime.value = 0
        recordingProgress.value = 0
        
        // 设置录音时间计时器
        recordingInterval.value = setInterval(() => {
          recordingTime.value++
          recordingProgress.value = Math.min(100, (recordingTime.value / 60) * 100) // 假设最长60秒
          
          // 防止录音过长
          if (recordingTime.value >= 60) {
            handleStopRecording()
          }
        }, 1000)
        
        showResult.value = false
        errorMessage.value = ''
        
      } catch (error) {
        console.error('开始录音失败:', error)
        // 根据不同类型的错误提供更具体的提示
        if (error.name === 'NotFoundError' || error.message.includes('Requested device not found')) {
          errorMessage.value = '未找到可用的录音设备，请确保您的设备已连接麦克风'
        } else if (error.name === 'NotAllowedError' || error.message.includes('Permission denied')) {
          errorMessage.value = '麦克风权限被拒绝，请在浏览器设置中允许麦克风访问'
        } else if (error.name === 'NotReadableError') {
          errorMessage.value = '麦克风正在被其他程序占用，请关闭其他使用麦克风的程序后重试'
        } else {
          errorMessage.value = '无法访问麦克风，请检查权限设置或设备连接'
        }
        showResult.value = true
      }
    }
    
    // 停止录音
    const handleStopRecording = () => {
      if (mediaRecorder.value && recording.value) {
        mediaRecorder.value.stop()
        recording.value = false
        
        if (recordingInterval.value) {
          clearInterval(recordingInterval.value)
          recordingInterval.value = null
        }
      }
    }
    
    // 处理音频文件上传
    const handleAudioUpload = (file) => {
      audioFile.value = file
      
      // 创建预览URL
      if (audioPreviewUrl.value) {
        URL.revokeObjectURL(audioPreviewUrl.value)
      }
      audioPreviewUrl.value = URL.createObjectURL(file)
      
      recordingData.value = null
      recordingTime.value = 0
      showResult.value = false
      errorMessage.value = ''
      
      return false // 阻止自动上传
    }
    
    // 识别语音
    const handleRecognizeSpeech = async () => {
      if (!audioFile.value && !recordingData.value) {
        errorMessage.value = '请先录音或上传音频文件'
        showResult.value = true
        return
      }
      
      loading.value = true
      errorMessage.value = ''
      showResult.value = true
      
      try {
        let file = audioFile.value
        
        // 如果是录音数据，创建一个File对象
        if (!file && recordingData.value) {
          const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
          file = new File([recordingData.value], `recording_${timestamp}.wav`, { type: 'audio/wav' })
        }
        
        // 调用API进行语音识别
        const result = await ttsApi.recognizeSpeech(file, sttLanguage.value)
        
        // 显示识别结果
        ttsFormData.text = result.text
        
        // 如果当前在语音转文字选项卡，切换到文字转语音选项卡
        activeTab.value = 'tts'
        
      } catch (error) {
        console.error('语音识别失败:', error)
        errorMessage.value = error.message || '语音识别失败，请稍后重试'
      } finally {
        loading.value = false
      }
    }
    
    // 组件挂载时加载数据
    onMounted(() => {
      loadLanguages()
      loadVoices()
    })
    
    // 组件卸载时清理资源
    onUnmounted(() => {
      if (recordingInterval.value) {
        clearInterval(recordingInterval.value)
      }
      
      if (mediaRecorder.value && recording.value) {
        mediaRecorder.value.stop()
      }
      
      if (audioPreviewUrl.value) {
        URL.revokeObjectURL(audioPreviewUrl.value)
      }
    })
    
    return {
      ttsFormData,
      spellingFormData,
      advancedSpellingFormData,
      useAdvancedSpelling,
      voices,
      languages,
      audioUrl,
      loading,
      errorMessage,
      showResult,
      spellingInfo,
      spellingText,
      getLanguageLabel,
      onLanguageChange,
      handleConvert,
      handleSpelling,
      handleAdvancedSpelling,
      handleClear,
      handleDownload,
      // 录音转文字相关
      activeTab,
      sttLanguage,
      recording,
      recordingData,
      recordingTime,
      recordingProgress,
      audioFile,
      audioPreviewUrl,
      handleTabClick,
      handleStartRecording,
      handleStopRecording,
      handleAudioUpload,
      handleRecognizeSpeech
    }
  }
}
</script>

<style scoped>
.kitten-tts-app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background-color: #f5f7fa;
  }
  
  .spelling-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  
  .spelling-hint {
    color: #606266;
    font-size: 12px;
    margin: 0;
    padding-left: 4px;
  }

.el-header {
  background-color: #f7f7f7;
  padding: 20px;
  text-align: center;
  border-bottom: 1px solid #e0e0e0;
}

.el-header h1 {
  margin: 0 0 10px 0;
  color: #303133;
}

.el-header p {
  margin: 0;
  color: #606266;
}

.el-main {
  padding: 20px;
  flex: 1;
}

.el-footer {
  text-align: center;
  padding: 20px;
  background-color: #f7f7f7;
  border-top: 1px solid #e0e0e0;
}

.tts-form-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.form-actions {
  display: flex;
  justify-content: flex-start;
  margin-top: 20px;
  gap: 10px;
}

/* 录音转文字相关样式 */
.stt-container {
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 5px;
}

.stt-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.stt-btn {
  min-width: 120px;
}

.recording-status {
  margin: 15px 0;
  padding: 10px;
  background-color: #fff3cd;
  border: 1px solid #ffeaa7;
  border-radius: 5px;
}

.recording-status p {
  margin: 5px 0 0 0;
  color: #856404;
}

.audio-preview {
  margin: 15px 0;
  padding: 10px;
  background-color: #d4edda;
  border: 1px solid #c3e6cb;
  border-radius: 5px;
}

.audio-preview p {
  margin: 0 0 10px 0;
  color: #155724;
}

.stt-language-selection {
  margin-top: 15px;
}

.result-card {
  margin-top: 20px;
}

.loading-container {
  text-align: center;
  padding: 40px 0;
}

.error-container {
  margin-top: 10px;
}

.success-container {
  margin-top: 10px;
}

.audio-controls {
  margin-top: 20px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.audio-controls audio {
  flex: 1;
}

.download-btn {
  white-space: nowrap;
}

.spelling-info-container {
  margin-top: 20px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border-left: 4px solid #409eff;
}

.spelling-text {
  margin-bottom: 10px;
  padding: 8px 0;
}

.spelling-details {
  padding: 8px 0;
  word-break: break-word;
  color: #606266;
}
</style>